using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

using Deepcode.Flux.Core.Data;
using Deepcode.Flux.Core.Systems.Scheduler;
using Deepcode.Flux.Core.Services.State;
using Deepcode.Flux.Core.Systems.Audit.Quick;

public partial class Private_Config_Scheduled_Default : Deepcode.Flux.Core.UI.AdministrationModulePage
{
	#region Permission Code Override
	public override string RequiredPermissionCode { get { return "FluxGeneralAdmin"; } }
	#endregion
	#region Page Load event
	/// <summary>
	/// Page Load event
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	protected void Page_Load(object sender, EventArgs e)
	{
		if (!Page.IsPostBack)
		{
			LoadState();
			BindDataGrid();
		}
	}
	#endregion
	#region Initialisation
	/// <summary>
	/// OnInit - hooks up the data paging handler, 
	/// rpp change handler and item command handlers
	/// </summary>
	/// <param name="e"></param>
	protected override void OnInit(EventArgs e)
	{
		base.OnInit(e);
		datapager.OnRepage += new Deepcode.Flux.Core.UI.Controls.DataPager.PagerRepage(BindDataGrid);
		datapager.OnRPPChanged += new Deepcode.Flux.Core.UI.Controls.DataPager.RPPChanged(RowsPerPageChange);
		datagrid.ItemCommand += new DataGridCommandEventHandler(GridCommand);
		datagrid.SortDirectionCommand += new Deepcode.Flux.Core.UI.Controls.StandardDataGrid.OnSortDirectionCommand(GridSortDirection);
		datagrid.ItemDataBound += new DataGridItemEventHandler(GridItemBound);
	}
	#endregion
	#region Data binding and paging events
	/// <summary>
	/// Data binding
	/// </summary>
	private void BindDataGrid()
	{
		// Add javascript call to delete buttons
		datagrid.BindJavascript("btnDelete", "onclick", "return ConfirmDelete();");
		// Set rows per page from registry
		datapager.RowsPerPage = this.UserSetting("RowsPerPage", 10);
	
		// Get and bind the data
		Tasks tasks = new Tasks();
		datapager.DataSource = tasks.GetAllTasks( this.CurrentSortOrder, this.CurrentSortDirection );
		datapager.DataBind();
	}
	/// <summary>
	/// A data item has been bound to the grid
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	void GridItemBound(object sender, DataGridItemEventArgs e)
	{
		if( e.Item.DataItem == null ) return;
		if( !(e.Item.DataItem is Task) ) return;

		Task item = (Task) e.Item.DataItem;

		Label labelStatus = (Label) e.Item.FindControl("labelStatus");
		if (labelStatus != null)
		{
			// The task no longer runs
			if (item.Finished ||
				((item.TaskExpires) && (item.ExpireTask < DateTime.Now)) ||
				(item.TimesRemaining == 0))
			{
				labelStatus.CssClass = "DangerLink";
				labelStatus.Text = "X";
			}
			else
			{
				labelStatus.CssClass = "SafeLink";
				labelStatus.Text = "!";
			}
		}

		Label labelSchedule = (Label) e.Item.FindControl("labelSchedule");
		if (labelSchedule != null)
		{
			if (item.Frequency == TaskFrequency.OnceOnly)
				labelSchedule.Text = "Once only";
			else
			{
				string text = String.Format("Every {0} {1}{2}",
					item.Interval,
					item.Frequency.ToString(),
					item.Interval > 1 ? "s" : "");
				labelSchedule.Text = text;
			}
		}
	}
	/// <summary>
	/// Paging control has set a new number of rows per page - store in user registry
	/// </summary>
	/// <param name="NewRPP"></param>
	void RowsPerPageChange(int NewRPP)
	{
		this.SetUserSetting("RowsPerPage", NewRPP);
	}
	#endregion
	#region User interactions
	/// <summary>
	/// Command received from the data grid
	/// </summary>
	/// <param name="source"></param>
	/// <param name="e"></param>
	void GridCommand(object source, DataGridCommandEventArgs e)
	{
		if( e.Item.ItemType == ListItemType.Footer ||
			e.Item.ItemType == ListItemType.Header ||
			e.Item.ItemType == ListItemType.Pager ||
			e.Item.ItemType == ListItemType.Separator ) return;

		// Get the key of the row being actioned 
		int rowKey = (int) datagrid.DataKeys[e.Item.ItemIndex];

		// PROCESS COMMANDS
		if( e.CommandName == "Delete" )
		{
			Tasks tasks = new Tasks();
			Task  task = tasks.GetTaskByID( rowKey );
			tasks.DeleteByID( rowKey );

			QuickAudit.RaiseImportant(
				new AuditUser(),
				"Flux", "Scheduled Tasks",
				"deleted scheduled task ({0})", task.TaskName);

			this.BindDataGrid();
			return;
		}
		if( e.CommandName == "Edit" )
		{
			string url = String.Format("ui_form.aspx?ID={0}&state={1}", rowKey, this.SaveState());
			Response.Redirect( url, true );
			return;
		}
	}
	/// <summary>
	/// User clicked the add new button
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	protected void btnAddNew_Click(object sender, EventArgs e)
	{
		string url = String.Format("ui_form.aspx?state={0}", this.SaveState());
		Response.Redirect(url, true);
	}
	/// <summary>
	/// Poll any outstanding tasks immediately
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	protected void btnPollNow_Click(object sender, EventArgs e)
	{
		QuickAudit.RaiseImportant(
			new AuditUser(),
			"Flux", "Scheduled Tasks",
			"forced a poll of all tasks");

		string url = String.Format("~/admin/Public/Schedule/");
		Response.Redirect(url, true);
	}
	#endregion
	#region State Remember/Recall
	/// <summary>
	/// Load current state from a string on the url
	/// </summary>
	private void LoadState()
	{
		StateRemember r = new StateRemember(Request["state"]);
		datapager.StartRow = r.Recall("StartRow", 1);
		CurrentSortOrder = (TaskSortOrder)r.Recall("SortOrder", TaskSortOrder.TaskName);
		CurrentSortDirection = (DataSortDirection)r.Recall("SortDirection", DataSortDirection.ASCENDING);
		datagrid.CurrentSortDirection = CurrentSortDirection;
		datagrid.CurrentSort = CurrentSortOrder.ToString();
	}
	/// <summary>
	/// Save current state to a string for later recall
	/// </summary>
	/// <returns></returns>
	public string SaveState()
	{
		StateRemember r = new StateRemember();
		r.Remember("StartRow", datapager.StartRow);
		r.Remember("SortOrder", CurrentSortOrder);
		r.Remember("SortDirection", CurrentSortDirection);
		return r.ToString();
	}
	#endregion

	#region ViewState storage
	/// <summary>
	/// Stores the current sort order in the viewstate
	/// </summary>
	public TaskSortOrder CurrentSortOrder
	{
		get
		{
			object o = ViewState["CurrentSortOrder"];
			if (o == null) return TaskSortOrder.TaskName;
			return (TaskSortOrder)o;
		}
		set
		{
			ViewState["CurrentSortOrder"] = value;
		}
	}
	/// <summary>
	/// Stores the current sort direction
	/// </summary>
	public DataSortDirection CurrentSortDirection
	{
		get
		{
			object o = ViewState["CurrentSortDirection"];
			if (o == null) return DataSortDirection.ASCENDING;
			return (DataSortDirection)o;
		}
		set
		{
			ViewState["CurrentSortDirection"] = value;
		}
	}
	#endregion
	#region Sorting
	/// <summary>
	/// User has changed the sort direction or sort order
	/// </summary>
	/// <param name="source"></param>
	/// <param name="SortExpression"></param>
	/// <param name="Direction"></param>
	void GridSortDirection(object source, string SortExpression, DataSortDirection Direction)
	{
		this.CurrentSortDirection = Direction;

		switch (SortExpression)
		{
			case "TaskName":
				this.CurrentSortOrder = TaskSortOrder.TaskName;
				break;
			case "ExecuteNext":
				this.CurrentSortOrder = TaskSortOrder.ExecuteNext;
				break;
			default:
				this.CurrentSortOrder = TaskSortOrder.TaskName;
				break;
		}
		this.BindDataGrid();
	}
	#endregion
}
